package com.seer.srd.qingdao

import com.seer.srd.BusinessError
import com.seer.srd.util.loadConfig

val CUSTOM_CONFIG = loadConfig("srd-config.yaml", CustomConfig::class) ?: CustomConfig()

const val ipv4Pattern =
    "^(((\\d{1,2})|(1\\d{2})|(2[0-4]\\d)|(25[0-5]))\\.){3}((\\d{1,2})|(1\\d{2})|(2[0-4]\\d)|(25[0-5]))$"

class CustomConfig {
    //protect vital operation
    var userConfig = emptyList<UserConfig>()

    //params setting
    var bufferAreaParam: Int = -1
    var tempAreaParam: Map<String, Int> = emptyMap()

    var plc: Map<String, PlcConfig> = emptyMap()

    var galleryTempArea: Map<String, Array<String>> = emptyMap()

    var galleryBufferArea: Map<String, Array<String>> = emptyMap()

    var store: Map<String, String> = emptyMap()

    var operateHeight: Map<String, OperateHeightInfo> = emptyMap()

    // 看板核对的库位的名称
    var boardCheckSiteId = "Check01"

    var storagePlcConfig = StoragePlcConfig()

    // 创建物料转运（暂存区 -> 缓存区）任务时，用到的柔性任务的名称
    var taskDefNameMatTransfer = "TaskDefMatTransfer"

    // 创建物料入库（缓存区 -> 立库入库口）任务时，用到的柔性任务的名称
    var taskDefNameMatInStoreA = "TaskDefMatInStoreA"

    var taskDefNameMatInStoreB = "TaskDefMatInStoreB"

    // 此配置仅在开发调试时使用
    //  - true: 库位状态满足创建任务的条件时，不创建任务。
    //  - false: 库位状态满足创建任务的条件时，会创建任务。
    var doNotCreateTaskWhenSitesAvailable = false

    // 物料暂存区每个巷道的库位的最大数量
    var maxSiteQtyOfWBGalleries = 8

    var base_start_height = 0.045

    var base_end_height = 0.345

    var rowZC = 8

    var rowRK = 4

    var roboViewConfig= RoboViewConfig()

}

class UserConfig {
    var workStation: String = ""
    var pwd: String = ""
}

class PlcConfig {
    var host = ""
    var port = -1
    var address = Address()
}

class RoboViewConfig{
    var host = ""
    var port = -1
}

class Address {
    var bigTrayOn = -1
    var smallTrayOn = -1
    var bigFull = -1
    var smallFull = -1
}

class OperateHeightInfo {
    var space = 0.0
    var upraise = 0.0
}

data class StoragePlcConfig(
    var host: String = "",
    var port: Int = 0,
    var unitId: Int = 0,                    // 等价于 modbus 的 slaveId
    var addressType: String = "1x",         // Modbus 的地址类型（0x, 1x, 3x, 4x）
    var bigTrayOn: Int = -1,                // 大库-母托盘到位信号
    var bigEmpty: Int = -1,                 // 大库-母托盘无物料信号
    var smallTrayOn: Int = -1,              // 小库-母托盘到位信号
    var smallEmpty: Int = -1                // 小库-母托盘无物料信号
) {
    fun check() {
        if (!host.matches(Regex(ipv4Pattern))) throw BusinessError("立库对接模块的 IP 地址配置异常！")
        if (port !in 0..65535) throw BusinessError("立库对接模块的端口号配置异常！")
        if (addressType !in listOf("0x", "1x", "3x", "4x"))
            throw BusinessError("无法识别 Modbus 地址类型（${addressType}），请检查配置文件！期望值为（0x, 1x, 3x, 4x）")
        if (bigTrayOn !in 0..65535) throw BusinessError("立库对接模块的“大库-母托盘到位信号（bigTrayOn）”地址配置异常！")
        if (bigEmpty !in 0..65535) throw BusinessError("立库对接模块的“大库-母托盘无物料信号（bigEmpty）”地址配置异常！")
        if (smallTrayOn !in 0..65535) throw BusinessError("立库对接模块的“小库-母托盘到位信号（smallTrayOn）”地址配置异常！")
        if (smallEmpty !in 0..65535) throw BusinessError("立库对接模块的“小库-母托盘无物料信号（smallEmpty）”地址配置异常！")
    }
}
